1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 import javax.security.sasl.*;
36 import javax.security.auth.callback.*;
37 import java.security.Security;
38 import java.util.*;
39
40 public class PrivacyRc4 {
41 private static final String MECH = "DIGEST-MD5";
42 private static final String SERVER_FQDN = "machineX.imc.org";
43 private static final String PROTOCOL = "jmx";
44
45 private static final byte[] EMPTY = new byte[0];
46
47 private static String pwfile, namesfile, proxyfile;
48 private static boolean auto;
49 private static boolean verbose = false;
50
51 private static byte[][] clntdata, srvdata;
52
53 private static void init(String[] args) throws Exception {
54 if (args.length == 0) {
55 pwfile = "pw.properties";
56 namesfile = "names.properties";
57 auto = true;
58 } else {
59 int i = 0;
60 if (args[i].equals("-m")) {
61 i++;
62 auto = false;
63 }
64 if (args.length > i) {
65 pwfile = args[i++];
66
67 if (args.length > i) {
68 namesfile = args[i++];
69
70 if (args.length > i) {
71 proxyfile = args[i];
72 }
73 }
74 } else {
75 pwfile = "pw.properties";
76 namesfile = "names.properties";
77 }
78 }
79
80 initData();
81 }
82
83
84 public static void main(String[] args) throws Exception {
85
86 init(args);
87
88 CallbackHandler clntCbh = new ClientCallbackHandler(auto);
89
90 CallbackHandler srvCbh =
91 new PropertiesFileCallbackHandler(pwfile, namesfile, proxyfile);
92
93 Map srvProps = new HashMap();
94 srvProps.put(Sasl.QOP, "auth-conf");
95
96 Map clntProps = new HashMap();
97 clntProps.put(Sasl.QOP, "auth-conf");
98 clntProps.put("com.sun.security.sasl.digest.cipher", "rc4-56");
99
100 SaslClient clnt = Sasl.createSaslClient(
101 new String[]{MECH}, null, PROTOCOL, SERVER_FQDN, clntProps, clntCbh);
102
103 SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
104 srvProps, srvCbh);
105
106 if (clnt == null) {
107 throw new IllegalStateException(
108 "Unable to find client impl for " + MECH);
109 }
110 if (srv == null) {
111 throw new IllegalStateException(
112 "Unable to find server impl for " + MECH);
113 }
114
115 byte[] response = (clnt.hasInitialResponse()?
116 clnt.evaluateChallenge(EMPTY) : EMPTY);
117 byte[] challenge;
118
119 while (!clnt.isComplete() || !srv.isComplete()) {
120 challenge = srv.evaluateResponse(response);
121
122 if (challenge != null) {
123 response = clnt.evaluateChallenge(challenge);
124 }
125 }
126
127 if (clnt.isComplete() && srv.isComplete()) {
128 if (verbose) {
129 System.out.println("SUCCESS");
130 System.out.println("authzid is " + srv.getAuthorizationID());
131 }
132 } else {
133 throw new IllegalStateException("FAILURE: mismatched state:" +
134 " client complete? " + clnt.isComplete() +
135 " server complete? " + srv.isComplete());
136 }
137
138
139 int count = 0;
140 for (int i = 0; i < clntStrs.length; i++) {
141 byte[] orig = clntdata[i];
142 byte[] wrapped = clnt.wrap(clntdata[i], 0, clntdata[i].length);
143 byte[] unwrapped = srv.unwrap(wrapped, 0, wrapped.length);
144
145 if (!Arrays.equals(orig, unwrapped)) {
146 throw new SaslException("Server cannot unwrap client data");
147 }
148
149 byte[] sorig = srvdata[i];
150 byte[] swrapped = srv.wrap(srvdata[i], 0, srvdata[i].length);
151 byte[] sunwrapped = clnt.unwrap(swrapped, 0, swrapped.length);
152
153 if (!Arrays.equals(sorig, sunwrapped)) {
154 throw new SaslException("Client cannot unwrap server data");
155 }
156 ++count;
157 }
158
159 if (verbose) {
160 System.out.println(count + " sets of wrap/unwrap between client/server");
161 }
162
163 clnt.dispose();
164 srv.dispose();
165 }
166
167 private static final String[] srvStrs = new String[] {
168 "A is the 1st letter",
169 "B is the 2nd letter",
170 "C is the 3rd letter",
171 "D is the 4th letter",
172 "E is the 5th letter",
173 "F is the 6th letter",
174 "G is the 7th letter",
175 "H is the 8th letter",
176 "I is the 9th letter",
177 "J is the 10th letter",
178 "K is the 11th letter",
179 "L is the 12th letter",
180 "M is the 13th letter",
181 };
182
183 private static final String[] clntStrs = new String[] {
184 "0",
185 "1",
186 "2",
187 "3",
188 "4",
189 "5",
190 "6",
191 "7",
192 "8",
193 "9",
194 "10",
195 "11",
196 "12",
197 };
198
199 private static void initData() {
200 clntdata = new byte[clntStrs.length][];
201 for (int i = 0; i < clntStrs.length; i++) {
202 clntdata[i] = clntStrs[i].getBytes();
203 }
204
205 srvdata = new byte[srvStrs.length][];
206 for (int i = 0; i < srvStrs.length; i++) {
207 srvdata[i] = srvStrs[i].getBytes();
208 }
209 }
210 }